package com.atguigu.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.order.bean.Order;
import com.atguigu.order.bean.User;
import com.atguigu.order.feign.LoginFeignClient;
import com.atguigu.order.properties.OrderProperties;
import com.atguigu.order.service.OrderService;
import com.fasterxml.jackson.databind.JsonNode;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.concurrent.ExecutionException;
//@RequestMapping("/api/order")
@Slf4j
//@RefreshScope //自动刷新配置
@RestController
@Tag(name = "订单服务",description = "订单服务接口")
public class OderController {
    @Autowired
    OrderService orderService;

//    @Value("${order.timeout}")
//    String timeout;
//    @Value("${order.auto-confirm}")
//    String auto_confirm;
    @Autowired
    OrderProperties orderProperties;

    @Autowired
    LoginFeignClient loginFeignClient;

    @PostMapping("/login")
    @Operation(summary = "远程登录")
    public String login(@Parameter (
                        description = "用户信息",
                        required = true,
                        example = "{\"phone\":\"13800000001\",\"password\":\"<PASSWORD>\"}",
                        schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = User.class)
                        )
                        @RequestBody User user){
        return loginFeignClient.login(user);
    }

    @GetMapping("/config")
    @Operation(summary = "获取配置信息")
    public String config(){
        return "order.timout="+orderProperties.getTimeout()+"\norder.auto-confirm="+orderProperties.getAutoConfirm()+"\norder.db-url="+orderProperties.getDbUrl();
    }
    //创建订单
    @GetMapping("/create")
    @Operation(summary = "创建订单")
    public Order createOrder(
            @Parameter (
                    description = "商品id",
                    required = true,
                    example = "1"
            )
            @RequestParam("productId") Long productId,
            @Parameter (
                    description = "用户id",
                    required = true,
                    example = "1"
            )
            @RequestParam("userId") Long userId){
        Order order = orderService.createOrder(productId, userId);
        return order;
    }
    @GetMapping("/seckill")
    @Operation(summary = "秒杀")
    @SentinelResource(value = "seckill-order",fallback = "seckillFallback")
    //fallback 要用Throwable捕获异常，这个可以捕获业务逻辑错误 blockHandler不能捕获业务逻辑错误 使用的是BlockException
    public Order seckill(
            @Parameter (
                    description = "商品id",
                    required = true,
                    example = "1"
            )
            @RequestParam("productId") Long productId,
            @Parameter (
                    description = "用户id",
                    required = true,
                    example = "1"
            )
            @RequestParam("userId") Long userId){
        Order order = orderService.createOrder(productId, userId);
        order.setId(Long.MAX_VALUE);
        return order;
    }

    public Order seckillFallback(Long productId, Long userId, Throwable e){
        Order order = orderService.createOrder(productId, userId);
        order.setId(Long.MAX_VALUE);
        order.setNickName("未知用户");
        order.setProductList(null);
        order.setTotalAmount(new BigDecimal(0));
        order.setAddress("异常信息："+e.getClass());
        return order;
    }

    @GetMapping("/writeDB")
    @Operation(summary = "写入数据库")
    public String wirteDB(){
        return "写入数据库成功";
    }
    @GetMapping("/readDB")
    @Operation(summary = "读取数据库")
    public String readDB(){
        log.info("开始读取数据库");
        return "读取数据库成功";
    }

}
